﻿#region Copyright (C) 2008, 2009 StreamTv

/* 
 *      Copyright (C) 2008, 2009 StreamTv
 *      http://code.google.com/p/mpstreamtv/
 *
 *  This Program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *   
 *  This Program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *   
 *  You should have received a copy of the GNU General Public License
 *  along with GNU Make; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
 *  http://www.gnu.org/copyleft/gpl.html
 *
 */

#endregion

#region Imports
using System;
using System.IO;
using System.Runtime.InteropServices;
#endregion

namespace TimeShifting.Media
{
    /// <summary>
    /// Used to load media and any associated encoders required.
    /// </summary>
    public class MediaFactory
    {
        #region Public methods

        public Stream Load(String path, Encoders.TranscodeOptions settings)
        {
            Stream media;
            // Load the file up.
            if (path.EndsWith(".tsBuffer", StringComparison.InvariantCultureIgnoreCase))
                media = new Format.TsBuffer(path);
            else
                media = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

            // Try and let the buffer build up.
            try
            {
                // Check if there is enough data in the buffer.
                for (int i = 0; i < 10000; i++)
                {
                    // If greater then 320Kb is built up were set.
                    if (media.Length > 327680)
                    {
                        break;
                    }

                    System.Threading.Thread.Sleep(1);
                }
            }
            catch (NotSupportedException) // Ignored, doesn't support length property.
            {
            }

            // Check if transcoding is required.
            if (!settings.IsRequired)
                return media;

            // Transcoding required, determine which encoder to use.
            try
            {
                Stream transcoder;

                switch (settings.Encoder.ToLower())
                {
                    case "mencoder":
                        transcoder = new TimeShifting.Media.Encoders.MEncoder(media, settings);

                        return transcoder;
                    case "ffmpeg":
                        transcoder = new TimeShifting.Media.Encoders.FFMpeg(media, settings);

                        return transcoder;
                    default:
                        return null;
                }
            }
#if DEBUG
            catch (Exception e)
            {
                throw new Exception("Problem loading transcoder: {0}", e);
            }
#else
            catch (Exception e)
            {
                TvLibrary.Log.Log.Error("StreamTv: TimeShift - Problem loading transcoder: {0}", e.Message);
                return null;
            }
#endif
        } // Load

        public Stream Load(Uri url, Encoders.TranscodeOptions settings)
        {
            Stream media;
            // Load the file up.
            if (url.AbsoluteUri.EndsWith(".tsBuffer", StringComparison.InvariantCultureIgnoreCase))
                media = new Format.TsBuffer(url.AbsoluteUri);
            else
                media = new FileStream(url.AbsoluteUri, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

            // Try and let the buffer build up.
            try
            {
                // Check if there is enough data in the buffer.
                for (int i = 0; i < 10000; i++)
                {
                    // If greater then 320Kb is built up were set.
                    if (media.Length > 327680)
                    {
                        break;
                    }

                    System.Threading.Thread.Sleep(1);
                }
            }
            catch (NotSupportedException) // Ignored, doesn't support length property.
            {
            }

            // Check if transcoding is required.
            if (!settings.IsRequired)
                return media;

            // Transcoding required, determine which encoder to use.
            try
            {
                switch (settings.Encoder.ToLower())
                {
                    case "mencoder":
                        Encoders.MEncoder trancoder = new TimeShifting.Media.Encoders.MEncoder(media, settings);

                        return trancoder;
                    default:
                        return null;
                }
            }
#if DEBUG
            catch (Exception e)
            {
                throw new Exception("Problem loading transcoder: {0}", e);
            }
#else
            catch (Exception e)
            {
                TvLibrary.Log.Log.Error("StreamTv: TimeShift - Problem loading transcoder: {0}", e.Message);
                return null;
            }
#endif
        } // Load
        #endregion
    }
}
